package com.tbl.modules.wms.service.Impl.storageinfo;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.tbl.common.utils.DateUtils;
import com.tbl.common.utils.PageTbl;
import com.tbl.common.utils.PageUtils;
import com.tbl.common.utils.StringUtils;
import com.tbl.modules.platform.util.DeriveExcel;
import com.tbl.modules.wms.dao.storageinfo.StorageInfoDAO;
import com.tbl.modules.wms.entity.instorage.InstorageDetail;
import com.tbl.modules.wms.entity.storageinfo.StorageInfo;
import com.tbl.modules.wms.service.storageinfo.StorageInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 库存查询实现类
 * @author 70486
 */
@Service("storageInfoService")
public class StorageInfoServiceImpl extends ServiceImpl<StorageInfoDAO, StorageInfo> implements StorageInfoService {

    /**
     * 库存
     */
	@Autowired
	private StorageInfoDAO storageInfoDAO;
	
	 /**
     * 获取 退库回生产线
     * @param params
     * @return pageUtils
     */
	 @Override
    public PageUtils getReturnStockList(PageTbl pageTbl,Map<String, Object> params) {
        Page page = new Page(pageTbl.getPageno(), pageTbl.getPagesize(), pageTbl.getSortname(), "asc".equalsIgnoreCase(pageTbl.getSortorder()));
        return new PageUtils(page.setRecords(storageInfoDAO.getReturnStockList(page, params)));
    }

    /**
     * 获取 库存分页列表数据
     * @param params
     * @return pageUtils
     */
    @Override
    public PageUtils getStockList(PageTbl pageTbl,Map<String, Object> params) {
        Page page = new Page(pageTbl.getPageno(), pageTbl.getPagesize(), pageTbl.getSortname(), "asc".equalsIgnoreCase(pageTbl.getSortorder()));
        return new PageUtils(page.setRecords(storageInfoDAO.getStorageInfoList(page,params)));
    }
    
    /**
     * 获取导出列
     * @param map 查询条件勾选条件
     * @return List<StorageInfo>
     */
    @Override
    public List<StorageInfo> getAllLists(Map<String,Object> map) {
        String ids = (String)map.get("ids");
        map.put("ids", StringUtils.isNotBlank(ids)? Arrays.stream(ids.split(",")).map(s -> Long.parseLong(s.trim())).collect(Collectors.toList()):null);
        return storageInfoDAO.getAllLists(map);
    }

    /**
     * 获取导出列
     * @param ids 标签初始化表主键
     * @param qaCode 质保号
     * @return List<InstorageDetail>
     */
    @Override
    public List<InstorageDetail> getAllLists2(String ids, String qaCode) {
        List<InstorageDetail> lstInstorageDetail = storageInfoDAO.getAllLists2(qaCode, StringUtils.isNotEmpty(ids) ?
                Arrays.stream(ids.split(",")).map(s -> Long.parseLong(s.trim())).collect(Collectors.toList()) : null);
        lstInstorageDetail.forEach(instorageDetail -> {
            if("11".equals(instorageDetail.getStateStr())) {
                instorageDetail.setStateStr("生产退库");
            }else if("12".equals(instorageDetail.getStateStr())) {
                instorageDetail.setStateStr("生产退库");
            }else if("13".equals(instorageDetail.getStateStr())) {
                instorageDetail.setStateStr("报废");
            }else if("21".equals(instorageDetail.getStateStr())) {
                instorageDetail.setStateStr("调拨入库");
            }else if("31".equals(instorageDetail.getStateStr())) {
                instorageDetail.setStateStr("调拨出库");
            }else if("43".equals(instorageDetail.getStateStr())) {
                instorageDetail.setStateStr("入库中");
            }else if("44".equals(instorageDetail.getStateStr())) {
                instorageDetail.setStateStr("入库完成");
            }else if("45".equals(instorageDetail.getStateStr())) {
                instorageDetail.setStateStr("已退库");
            }else if("51".equals(instorageDetail.getStateStr())) {
                instorageDetail.setStateStr("移库入库");
            }else if("61".equals(instorageDetail.getStateStr())) {
                instorageDetail.setStateStr("移库出库");
            }else if("72".equals(instorageDetail.getStateStr())) {
                instorageDetail.setStateStr("拣货中");
            }else if("73".equals(instorageDetail.getStateStr())) {
                instorageDetail.setStateStr("出库完成");
            }else if("74".equals(instorageDetail.getStateStr())) {
                instorageDetail.setStateStr("预出库");
            }else if("81".equals(instorageDetail.getStateStr())) {
                instorageDetail.setStateStr("拆分");
            }else {
                instorageDetail.setStateStr("其他");
            }
        });
        return lstInstorageDetail;
    }

    /**
     * 导出Excel
     * @param response
     * @param path
     * @param lstStorageInfo
     * @param excelIndexArray
     */
    @Override
    public void toExcel(HttpServletResponse response, String path, List<StorageInfo> lstStorageInfo,String [] excelIndexArray) {
        try {
            String sheetName = "库存表" + "(" + DateUtils.getDay() + ")";
            if (path != null && !"".equals(path)) {
                sheetName = sheetName + ".xls";
            } else {
                response.setHeader("Content-Type", "application/force-download");
                response.setHeader("Content-Type", "application/vnd.ms-excel");
                response.setCharacterEncoding("UTF-8");
                response.setHeader("Expires", "0");
                response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
                response.setHeader("Pragma", "public");
                response.setHeader("Content-disposition", "attachment;filename=" + new String(sheetName.getBytes("gbk"),
                        "ISO8859-1") + ".xls");
            }

            if (lstStorageInfo!=null) {
                for (StorageInfo storageInfo : lstStorageInfo) {
                    if (storageInfo.getStorageType()!=null) {
                        if (storageInfo.getStorageType() == 0) {
                            storageInfo.setStorageTypeStr("正常生产");
                        } else if (storageInfo.getStorageType() == 1) {
                            storageInfo.setStorageTypeStr("销售退货");
                        } else if (storageInfo.getStorageType() == 2) {
                            storageInfo.setStorageTypeStr("外协采购");
                        }
                    }

                    //状态：0冻结(入库)；1正常；2锁定(出库);3待重新绑定rfid（按米出库剩余部分）
                    if (storageInfo.getState() == 0) {
                        storageInfo.setStateName("冻结(入库)");
                    } else if (storageInfo.getState() == 1) {
                        storageInfo.setStateName("正常");
                    } else if (storageInfo.getState() == 2) {
                        storageInfo.setStateName("锁定(出库)");
                    } else {
                        storageInfo.setStateName("未知");
                    }
                }
            }

            Map<String, String> mapFields = new LinkedHashMap<>();

            if (excelIndexArray.length==1&&"".equals(excelIndexArray[0])) {
                mapFields.put("qaCode", "质保单号");
                mapFields.put("batchNo", "批次号");
                mapFields.put("materialName", "物料名称");
                mapFields.put("factoryName", "厂区");
                mapFields.put("warehouseName", "仓库");
                mapFields.put("shelfCode", "库位");
                mapFields.put("salesName", "营销经理");
                mapFields.put("orderno", "订单号");
                mapFields.put("orderline", "订单行号");
                mapFields.put("entityNo", "工单号");
                mapFields.put("meter", "数量");
                mapFields.put("unit", "单位");
                mapFields.put("drumType", "盘类型");
                mapFields.put("model","盘规格");
                mapFields.put("outerDiameter","盘外径");
                mapFields.put("innerDiameter","盘内径");
                mapFields.put("weight", "重量");
                mapFields.put("colour", "颜色");
                mapFields.put("segmentno","段号");
                mapFields.put("dishcode", "盘号");
                mapFields.put("dishnumber", "盘踞编码");
                mapFields.put("storageTypeStr", "货物类型");
                mapFields.put("stateName", "状态");
            }else {
                for (String s : excelIndexArray) {
                    if ("2".equals(s)) {
                        mapFields.put("qaCode", "质保单号");
                    } else if ("3".equals(s)) {
                        mapFields.put("batchNo", "批次号");
                    } else if ("4".equals(s)) {
                        mapFields.put("materialName", "物料名称");
                    } else if ("5".equals(s)) {
                        mapFields.put("factoryName", "厂区");
                    } else if ("6".equals(s)) {
                        mapFields.put("warehouseName", "仓库");
                    } else if ("7".equals(s)) {
                        mapFields.put("shelfCode", "库位");
                    } else if ("8".equals(s)) {
                        mapFields.put("salesName", "营销经理");
                    } else if ("9".equals(s)) {
                        mapFields.put("orderno", "订单号");
                    } else if ("10".equals(s)) {
                        mapFields.put("orderline", "订单行号");
                    } else if ("11".equals(s)) {
                        mapFields.put("entityNo", "工单号");
                    } else if ("12".equals(s)) {
                        mapFields.put("meter", "数量");
                    } else if ("13".equals(s)) {
                        mapFields.put("unit", "单位");
                    } else if ("14".equals(s)) {
                        mapFields.put("drumType", "盘类型");
                    } else if ("15".equals(s)) {
                        mapFields.put("model", "盘规格");
                    } else if ("16".equals(s)) {
                        mapFields.put("outerDiameter", "盘外径");
                    } else if ("17".equals(s)) {
                        mapFields.put("innerDiameter", "盘内径");
                    } else if ("18".equals(s)) {
                        mapFields.put("weight", "重量");
                    } else if ("19".equals(s)) {
                        mapFields.put("colour", "颜色");
                    } else if ("20".equals(s)) {
                        mapFields.put("segmentno", "段号");
                    } else if ("21".equals(s)) {
                        mapFields.put("dishcode", "盘号");
                    } else if ("22".equals(s)) {
                        mapFields.put("dishnumber", "盘踞编码");
                    } else if ("23".equals(s)) {
                        mapFields.put("storageTypeStr", "货物类型");
                    } else if ("24".equals(s)) {
                        mapFields.put("stateName", "状态");
                    }
                }
            }

            DeriveExcel.exportExcel(sheetName, lstStorageInfo, mapFields, response, path);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 库存交易报表导出Excel
     * @param response
     * @param path
     * @param list
     */
    @Override
    public void toExcel2(HttpServletResponse response, String path, List<InstorageDetail> list) {
        try {
            String sheetName = "库存交易报表" + "(" + DateUtils.getDay() + ")";
            if (path != null && !"".equals(path)) {
                sheetName = sheetName + ".xls";
            } else {
                response.setHeader("Content-Type", "application/force-download");
                response.setHeader("Content-Type", "application/vnd.ms-excel");
                response.setCharacterEncoding("UTF-8");
                response.setHeader("Expires", "0");
                response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
                response.setHeader("Pragma", "public");
                response.setHeader("Content-disposition", "attachment;filename=" + new String(sheetName.getBytes("gbk"),
                        "ISO8859-1") + ".xls");
            }
            Map<String, String> mapFields = new LinkedHashMap<>();
            mapFields.put("stateStr", "交易类型");
            mapFields.put("qaCode", "质保号");
            mapFields.put("batchNo", "批次号");
            mapFields.put("dishcode", "盘号");
            mapFields.put("meter", "数量");
            mapFields.put("materialCode", "物料编码");
            mapFields.put("dishnumber", "盘具编码");
            mapFields.put("createTimeStr","创建时间");
            DeriveExcel.exportExcel(sheetName, list, mapFields, response, path);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
	 * 获取图表数据"库龄"占比
	 * return Map<String,Object>
	 */
    @Override
	public Map<String,Object> getLibraryAge() {
		Map<String,Object> map = new HashMap<>(4);
        int oneYear = storageInfoDAO.selectCount(new EntityWrapper<StorageInfo>()
                .addFilter("trunc(months_between(sysdate,INSTORAGETIME)/144)<=1",""));
        int twoYear = storageInfoDAO.selectCount(new EntityWrapper<StorageInfo>()
                .addFilter("trunc(months_between(sysdate,INSTORAGETIME)/144)<=2 and trunc(months_between(sysdate,INSTORAGETIME)/144)>1",""));
        int threeYear = storageInfoDAO.selectCount(new EntityWrapper<StorageInfo>()
                .addFilter("trunc(months_between(sysdate,INSTORAGETIME)/144)<=3 and trunc(months_between(sysdate,INSTORAGETIME)/144)>2",""));
        int other = storageInfoDAO.selectCount(new EntityWrapper<StorageInfo>()
        		.addFilter("trunc(months_between(sysdate,INSTORAGETIME)/12)>3 or trunc(months_between(sysdate,INSTORAGETIME)/12)=0", ""));
        int total = oneYear+twoYear+threeYear+other;
        if(total==0) {
        	map.put("oneYear", 0);
        	map.put("twoYear", 0);
        	map.put("threeYear", 0);
        	map.put("otherYear", 0);
        }else {
        	BigDecimal bDivisor;
        	BigDecimal divisor = new BigDecimal(Double.toString(total));
        	//计算各个年份的占比
        	bDivisor = new BigDecimal(Double.toString(oneYear));
        	map.put("oneYear", bDivisor.divide(divisor, 4, BigDecimal.ROUND_HALF_UP).doubleValue());
        	bDivisor = new BigDecimal(Double.toString(twoYear));
        	map.put("twoYear", bDivisor.divide(divisor, 4, BigDecimal.ROUND_HALF_UP).doubleValue());
        	bDivisor = new BigDecimal(Double.toString(threeYear));
        	map.put("threeYear", bDivisor.divide(divisor, 4, BigDecimal.ROUND_HALF_UP).doubleValue());
        	bDivisor = new BigDecimal(Double.toString(other));
        	map.put("otherYear", bDivisor.divide(divisor, 4, BigDecimal.ROUND_HALF_UP).doubleValue());
        }
        return map;
	}

    /**
     * 根据质保号获取库存主键字符拼接
     * @param qacodes 质保号数组
     * @return String 库存主键字符（1，2，3，4，5，6）
     * */
    @Override
    public String selectStorageInfoIdsByQacode(String [] qacodes){
        return storageInfoDAO.selectStorageInfoIdsByQacode(qacodes);
    }

    /**
     * 根据库位编码查询库存信息
     * @param factoryCode 厂区
     * @param warehouseCode 仓库
     * @param shelfCode 库位
     * @return StorageInfo
     * */
    @Override
    public List<StorageInfo> getStorageInfoByShelf(String factoryCode, String warehouseCode, String shelfCode){
        return storageInfoDAO.getStorageInfoByShelf(factoryCode, warehouseCode, shelfCode);
    }

    /**
     * 根据wms盘点单号主键修改库存米数，把库存米数更新为盘点米数
     * @param lstPlanId EBS盘点单号对应的多个wms盘点单主键集合
     * @param failQacodes EBS处理失败的质保号
     */
    @Override
    public void updateMeterByInventory(List<String> lstPlanId, List<String> failQacodes){
        storageInfoDAO.updateMeterByInventory(lstPlanId, failQacodes);
    }

    /**
     * 找出这个集结号下的所有上传米数盘点的数据中执行成功的,来对库存表进行更新
     * @param specialSign	集结号
     * @param failQacodes	失败的质保号
     */
    @Override
    public void updateStorageInfoMeterByInventoryRegistration(Long specialSign, List<String> failQacodes){
        storageInfoDAO.updateStorageInfoMeterByInventoryRegistration(specialSign, failQacodes);
    }
}
